<template>
  <a-form class="form" :model="formData">
    <template v-for="(module, index) in Data" :key="index">
      <a-form-item class="itemTitle">
        <div class="title">{{ numberToChinese(index + 1) + '、' + module.name }}</div>
      </a-form-item>
      <template v-for="(subitem, i) in module.list" :key="i">
        <visible-render height="50px">
          <a-form-item class="subitemName">
            <span
              >{{ i + 1 + '. ' + subitem.name
              }}<span>{{
                subitem.type.includes('单选')
                  ? '（单选）'
                  : subitem.type.includes('多选')
                    ? '（多选）'
                    : ''
              }}</span></span
            >
          </a-form-item>
          <template v-if="['单选', '单选+输入'].includes(subitem.type)">
            <a-form-item class="subitemName">
              <a-row :gutter="[48, 8]">
                <template v-for="(option, s) in subitem.options" :key="s">
                  <a-col>
                    <a-space>
                      <a-radio
                        :checked="subitem.value === option.value"
                        @change="radioChange(option, subitem)"
                        :disabled="disabled"
                        >{{ option.value }}</a-radio
                      >
                      <a-input
                        v-if="option.input"
                        style="width: 210px"
                        v-model:value="subitem.inputText"
                        @input="
                          () => {
                            subitem.value = option.value
                          }
                        "
                        :disabled="disabled"
                        autocomplete="off"
                        :maxlength="option.maxlength"
                        placeholder=""
                      />
                    </a-space>
                  </a-col>
                </template>
              </a-row>
            </a-form-item>
          </template>
          <template v-else-if="['多选', '多选+输入'].includes(subitem.type)">
            <a-form-item class="subitemNameCheckbox">
              <a-row :gutter="[48, 8]">
                <template v-for="(option, s) in subitem.options" :key="s">
                  <a-col>
                    <a-space>
                      <a-checkbox
                        :checked="subitem.value.includes(option.value)"
                        @change="multipleChange($event, option.value, subitem, s)"
                        :disabled="disabled"
                        >{{ option.value }}</a-checkbox
                      >
                      <a-input
                        v-if="option.input"
                        style="width: 210px"
                        v-model:value="subitem.inputText"
                        @input="
                          () => {
                            subitem.value = Array.from(new Set(subitem.value).add(option.value))
                          }
                        "
                        :disabled="disabled"
                        autocomplete="off"
                        :maxlength="option.maxlength"
                        placeholder=""
                      />
                    </a-space>
                  </a-col>
                </template>
              </a-row>
            </a-form-item>
          </template>
          <template v-else-if="subitem.type === '输入'">
            <a-form-item class="subitemNameCheckbox">
              <a-textarea
                class="textarea"
                v-model:value="subitem.value"
                @input="onInput"
                :disabled="disabled"
                placeholder="请输入你的回答"
                :maxlength="500"
                autoSize
              />
            </a-form-item>
          </template>
          <template v-else-if="subitem.type === '搜索输入'">
            <a-form-item class="subitemNameCheckbox">
              <a-textarea
                class="textarea"
                v-model:value="subitem.value"
                @input="onInput"
                :disabled="disabled"
                placeholder="请输入你的回答"
                :maxlength="500"
                autoSize
              />
            </a-form-item>
          </template>
          <template v-else-if="subitem.type === '数字选择'">
            <a-form-item class="subitemNameCheckbox">
              <div class="tags">
                <a-tag
                  class="tag"
                  :key="tag"
                  :color="subitem.value === subitem.config.min + tag - 1 ? '#108ee9' : ''"
                  v-for="tag in subitem.config.max - subitem.config.min"
                  @click="tagChange(subitem.config.min + tag - 1, subitem)"
                  >{{ subitem.config.min + tag - 1 }}</a-tag
                >
                <div class="start">{{ subitem.config.min_label }}</div>
                <div class="end">{{ subitem.config.max_label }}</div>
              </div>
            </a-form-item>
          </template>
        </visible-render>
        <slot name="custom" :item="subitem" :index="[index, i]" />
      </template>
    </template>
  </a-form>
</template>

<script setup lang="ts">
import { watch, ref } from 'vue'
import VisibleRender from '@/components/VisibleRender.vue'
import { numberToChinese, typeOf } from '@/utils/tools'

const Data = ref([])

const radioChange = (e, item) => {
  item.value = e.value
  item.sort = e.sort

  console.log(props.formData)
  formDataFilter()
}

const onInput = () => {
  formDataFilter()
}

const multipleChange = (e, val, item, i) => {
  if (e.target.checked) {
    if (item.options[i].exclusive) {
      item.value = [val]
      return
    }

    if (item.value.includes(val)) {
      return
    } else {
      for (let j = item.value.length; j > -1; j--) {
        const k = item.options.find((v) => {
          return item.value[j] === v.value && v.exclusive
        })
        if (k) {
          item.value.splice(j, 1)
        }
      }

      item.value.push(val)
    }
  } else {
    const i = item.value.findIndex((v) => {
      return v === val
    })
    if (i > -1) {
      item.value.splice(i, 1)
    } else {
      return
    }
  }

  item.sort = item.value.map((v) => {
    const c = item.options.find((u) => {
      return u.value === v
    })
    return c.sort
  })

  formDataFilter()
}

const tagChange = (e, subitem) => {
  subitem.value = e

  formDataFilter()
}

const transform = (obj) => {
  if (typeOf(obj.value) === 'string') {
    return new Function('x', 'return x ' + obj.operator + ' "' + obj.value + '"')
  } else {
    return new Function('x', 'return x ' + obj.operator + ' ' + obj.value)
  }
}

const transformCustom = (str, obj) => {
  const s = str.replace(/\$\{(.*?)\}/g, (_, key) => {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      return obj[key].value
    } else {
      throw new Error('自定义条件执行异常找不到变量')
    }
  })
  const f = new Function('x', 'return ' + s)
  console.log(f())
  return f()
}

const loop = (obj, d) => {
  if (obj.operator === 'AND') {
    return obj.conditions.every((v) => {
      if (v.operator !== 'AND' && v.operator !== 'OR') {
        if (v.operator === '填写完成') {
          return d[v.id].value.trim() !== ''
        } else {
          if (v.id === 'custom') {
            return transformCustom(v.value, d)
          } else if (d[v.id].type.includes('单选')) {
            return d[v.id].sort == v.value
          } else if (d[v.id].type.includes('多选')) {
            return d[v.id].sort.includes(v.value)
          } else if (d[v.id].type === '数字选择') {
            const f = transform(v)
            console.log(d[v.id].value)
            return f(d[v.id].value)
          } else if (d[v.id].type === '输入') {
            const f = transform(v)
            return f(d[v.id].value)
          }
          if (typeOf(d[v.id].value) === 'string') {
            return d[v.id].value.trim() !== ''
          } else if (typeOf(d[v.id].value) === 'array') {
            return d[v.id].value.length > 0
          } else {
            return true
          }
          // return f(d[v.id].value)
        }
      } else {
        return loop(v, d)
      }
    })
  } else if (obj.operator === 'OR') {
    return obj.conditions.some((v) => {
      if (v.operator !== 'AND' && v.operator !== 'OR') {
        if (v.operator === '填写完成') {
          return d[v.id].value.trim() !== ''
        } else {
          if (v.id === 'custom') {
            return transformCustom(v.value, d)
          } else if (d[v.id].type.includes('单选')) {
            return d[v.id].sort == v.value
          } else if (d[v.id].type.includes('多选')) {
            return d[v.id].sort.includes(v.value)
          } else if (d[v.id].type === '数字选择') {
            const f = transform(v)
            return f(d[v.id].value)
          } else if (d[v.id].type === '输入') {
            const f = transform(v)
            return f(d[v.id].value)
          }
          if (typeOf(d[v.id].value) === 'string') {
            return d[v.id].value.trim() !== ''
          } else if (typeOf(d[v.id].value) === 'array') {
            return d[v.id].value.length > 0
          } else {
            return true
          }
          // return f(d[v.id].value)
        }
      } else {
        return loop(v, d)
      }
    })
  }
  return true
}

const showCondition = (arr) => {
  const obj = {}
  arr.map((v) => {
    v.list.map((u) => {
      obj[u.id] = u
    })
  })

  const List = []

  for (const v of arr) {
    const L = v.list.filter((u) => {
      if (!u.showCondition) {
        return true
      }
      let show = true
      if (u.showCondition.hasOwnProperty('show')) {
        show = u.showCondition.show
      }
      let r
      try {
        r = loop(u.showCondition, obj)
      } catch (e) {
        throw new Error(`自定义条件执行异常，异常问题：${u.name}`)
      }
      if (show) {
        return r
      } else {
        return !r
      }
    })
    if (L.length) {
      List.push({
        ...v,
        list: L
      })
    }
  }

  return List
}

const formDataFilter = () => {
  console.time('1')
  if (props.condition) {
    Data.value = showCondition(props.formData)
  } else {
    Data.value = props.formData
  }
  console.timeEnd('1')
}

const props = defineProps({
  formData: {
    default: []
  },
  disabled: {
    default: false
  },
  condition: {
    default: false
  }
})
const emit = defineEmits(['update:formData', 'reset'])

watch(
  () => props?.formData,
  () => {
    formDataFilter()
  },
  {
    immediate: true
  }
)
</script>

<style lang="less" scope>
.ant-form-item {
  &.itemTitle {
    margin-bottom: 5px;
    .title {
      height: 32px;
      font-size: 14px;
      font-family:
        PingFang SC,
        PingFang SC;
      font-weight: 600;
      padding-left: 16px;
      line-height: 32px;
    }
  }
  &.subitemName {
    margin-bottom: 0px;
  }
  &.subitemNameCheckbox {
    margin-bottom: 0px;
  }
  .textarea {
    padding-left: 16px;
    padding-right: 16px;
    width: 50%;
  }
}

html[theme='light'] {
  .ant-form-item {
    font-size: 14px;
    &.itemTitle {
      background: #f7f8fa;
      .title {
        color: #1d2129;
      }
    }
  }
}
.red {
  color: #ff1313;
}
.tags {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  position: relative;
  padding-bottom: 32px;
  .start {
    position: absolute;
    left: 0;
    top: 32px;
  }
  .end {
    position: absolute;
    right: 0;
    top: 32px;
  }
  .tag {
    cursor: pointer;
    user-select: none;
  }
}
</style>
